#ifndef TEST_GRAPHICS_APPLICATION_H
#	define TEST_GRAPHICS_APPLICATION_H

#include "base/singleton.h"
#include "system/application.h"
#include "system/applicationsetup.h"
#include "system/window.h"
#include "system/timer.h"

#include "inputs/manager.h"
#include "inputs/command.h"

#include "renderwindow.h"
#include "indexbuffer.h"
#include "vertexbuffer.h"
#include "declaration.h"
#include "program.h"
#include "sampler.h"
#include "texture.h"

namespace test {
	namespace graffiti {

class Terrain;
class WindowEventListener;

class Application
:	public dw::system::Application
,	public dw::base::Singleton< Application, false >
{
public : //! @name dw::system::Application Events
	//! @{
	virtual bool onSetup(int argc, char** argv);
	virtual void onIdle();
	virtual void onShutdown();
	//! @}

public : //! @name State
	//! @{
	virtual Setup& getSetup() { return m_setup; }
	const dw::system::Window& getWindow() const { return *m_window; }
	//! @}

public : //! @name Callbacks
	//! @{
	void onSize(dw::system::Window* sender, dw::system::Window::SizeEventArg& eventArg) { ; }
	//! @}

protected : //! @name Construction & destruction
	//! @{
	friend class dw::base::Singleton< Application, false >;

	Application();
	~Application();
	//! @}

private : //! @name todo move those Data to test or test suite
	//! @{
	void draw();
	bool initTerrain();
	bool initProgram();
	bool initArrayBuffer();
	bool initImage();

	Setup m_setup;
	WindowEventListener* m_windowEventListener;

	dw::inputs::InputCommand m_mousePan;
	dw::inputs::InputCommand m_mouseRotate;
	dw::inputs::InputCommand m_wireframe;

	dw::system::Timer m_timer;
	dw::system::Window* m_window;
	dw::graffiti::RenderWindow* m_renderWindow;

	GLuint m_terrainVaoId[1];

	Terrain* m_terrain;
	
	glm::vec3 m_translation;
	glm::vec3 m_rotation;

	dw::graffiti::IndexBuffer* m_indexBuffer;
	dw::graffiti::VertexBuffer* m_vertexBuffer;
	dw::graffiti::VertexBuffer* m_colorBuffer;
	dw::graffiti::Program* m_program;
	dw::graffiti::Program* m_wireframeProgram;
	dw::uint32 m_terrainTrianglesCount;

	dw::uint32 m_imageSize;
	std::vector< dw::uint8 > m_image;

	dw::graffiti::Texture* m_texture;
	dw::graffiti::Sampler* m_sampler;

	bool m_drawWireframe;
	//! @}
};

	} // namespace graffiti
} // namespace test

#endif // !TEST_GRAPHICS_APPLICATION_H
